<template>
  <div>

    <VueDraggableNext class="dragArea list-group w-full" :list="list" @change="log">

      <n-tag type="primary" v-for="element in list"
              :key="element.name">
        {{ element.name }}
      </n-tag>

    </VueDraggableNext>

    <n-space style="margin-bottom: 10px" justify="space-between">
      <n-space>
        <n-select style="width: 150px" :options="videoCutPicType" v-model:value="extractOption">
        </n-select>
        <n-popconfirm
            @positive-click="batchScreenshot"
        >
          <template #trigger>
            <n-button type="primary" :loading="examplePicLoading">生成参考图</n-button>
          </template>
          确定批量生成参考图吗？
        </n-popconfirm>
        <n-button type="success" @click="deduplicationModalShow=true">图片去重</n-button>
        <n-button type="info" @click="removeMarkModalShow=true">批量模糊水印</n-button>
      </n-space>
    </n-space>
    <n-grid x-gap="12">
      <n-gi :span="14">
        <n-data-table
            v-model:checked-row-keys="checkedRowKeys"
            :single-line="false"
            :columns="createColumns"
            :data="videoTextList"
            :loading="tableLoading"
            :style="{ height: `${clientHeight - 165}px` }"
            :on-update:checked-row-keys="onUpdateCheckedRowKeys"
            flex-height
        />
      </n-gi>
      <n-gi :span="10">
        <n-card title="图片选择" :style="{ height: `${clientHeight - 165}px` }">
          <template #header-extra>
            <n-button type="primary" @click="randomScreentshot" :loading="randomScreentshotLoading">随机截图5张</n-button>
          </template>
          <n-grid x-gap="2" :cols="2">
            <n-gi v-for="imageFile in filterScreenshotList">
              <n-card>
                <template #cover>
                  <n-image
                      :width="300"
                      @click="clickImg(storyPaintLog)"
                      style="margin-left: 10px;"
                      :src=fileFunction.getViewFilePathByUserFileId(imageFile.userFileId)
                  />
                </template>
                <template #footer>
                  <n-checkbox @update:checked="examplePicSelect(imageFile)" v-model:checked="imageFile.checked">
                    {{ imageFile.fileName / 1000 }}
                  </n-checkbox>
                </template>
              </n-card>
            </n-gi>
          </n-grid>
        </n-card>
      </n-gi>
    </n-grid>
    <n-modal
        v-model:show="progressModal"
        class="custom-card"
        style="width: 500px"
        preset="card"
        :mask-closable="false"
        title="任务进度"
        size="huge"
        :bordered="false"
    >
      <n-h4>您一共需要生成{{totalNum}}张参考图</n-h4>
      <n-space justify="space-around">
        <n-statistic label="当前进度:" :value="finishNum">
          <template #prefix>
          </template>
          <template #suffix>
            / {{ totalNum }}
          </template>
        </n-statistic>
      </n-space>
      <n-progress
          type="line"
          :percentage=" finishNum === 0? 0 : Math.round(finishNum/totalNum *100) "
          :height="30"
          :border-radius="5"
          :fill-border-radius="0"
      />
    </n-modal>


    <n-modal
        v-model:show="deduplicationModalShow"
        class="custom-card"
        style="width: 500px"
        preset="card"
        :mask-closable="false"
        title="图片去重"
        size="huge"
        :bordered="false"
    >
      <n-form-item label="相似度阈值">
         <n-input-number
            v-model:value="similarity"
            :min="50"
            :max="99"
            :show-button="false"
            style="width: 100%"
            >
          <template #suffix>
            %
          </template>
        </n-input-number>
      </n-form-item>
      <template #footer>
        <n-button type="primary" @click="imageDeduplication" :loading="imageDeduplicationLoading" block>去重并合并分镜</n-button>
      </template>
    </n-modal>


    <n-modal
        v-model:show="addModalShow"
        style="width: 600px"
        preset="card"
        title="新增分镜"
        size="huge"
        :bordered="false"
    >
      <n-form>
        <n-h4>您当前在第<n-tag type="primary">{{addNum}}</n-tag>分镜插入分镜,新增分镜编号为:<n-tag type="primary">{{addNum+1}}</n-tag></n-h4>
        <n-form-item label="文本内容">
          <n-input type="textarea" style="height: 100px;" v-model:value="editDataForm.content"></n-input>
        </n-form-item>

        <n-row>
          <n-col :span="12">
            <n-form-item label="开始时间">
              <n-input-number
                  v-model:value="editDataForm.startTime"
                  :min="editDataForm.lastStartTime + 0.1"
                  :max="editDataForm.endTime - 0.1" :step="0.1">
              </n-input-number>
            </n-form-item>
          </n-col>
          <n-col :span="12">
            <n-form-item label="结束时间">
              <n-input-number v-model:value="editDataForm.endTime" readonly></n-input-number>
            </n-form-item>
          </n-col>
        </n-row>
      </n-form>
      <template #footer>
        <n-space justify="end">
          <n-button @click="addModalShow=false">取消</n-button>
          <n-button type="primary" @click="addOrUpdateBoard">确认</n-button>
        </n-space>
      </template>
    </n-modal>

    <n-modal
        v-model:show="removeMarkModalShow"
        class="custom-card"
        preset="card"
        :style="{
          width: '900px'
        }"
        title="选择水印区域"
        size="huge"
        :bordered="false"
    >
      <RemoveWaterMarker
          v-if="screenshotList!=null && screenshotList.length > 6"
         :screenshotList="screenshotList.slice(0,6)"
          :story="props.story"
          @loadSuccess-Event="loadSuccessEvent"
         >
      </RemoveWaterMarker>
    </n-modal>


  </div>
</template>
<script setup lang="ts">
import {NButton, NImage, NInput, NSelect, NTag, useMessage} from 'naive-ui'
import {h, nextTick, onMounted, reactive, ref} from "vue"
import {storyController} from "@/api/story/story.api"
import {storyBoardController} from "@/api/controller/story/storyBoard.api"
import {storeToRefs} from "pinia"
import {useSystemStore} from "@/store/modules/useSystemStore"
import {creatorDict} from '@/dictionary/creatorDict'
import fileFunction from "@/libs/globalFunction/file"
import {videoController} from "@/api/controller/video/videoController.api"
import RemoveWaterMarker from "@/components/removewatermarker/index.vue"
import { VueDraggableNext } from 'vue-draggable-next'

const message = useMessage()
const story = ref("")
const progressModal = ref(false)
const extractOption = ref("1")
const tableLoading = ref(false)
const {videoCutPicType} = creatorDict()
const videoTextList = ref([])
const checkedRowKeys = ref([0])
const screenshotList = ref([])
const filterScreenshotList = ref([])
const picMap = reactive(new Map([]));
const examplePicLoading = ref(false)
const totalNum = ref(0)
const finishNum = ref(0)
const deduplicationModalShow = ref(false)
const {
  clientHeight,
  layoutHeaderHeight,
  darkTheme,
  tabsHeight
} = storeToRefs(useSystemStore());

const similarity = ref(98)
const imageDeduplicationLoading = ref(false)
const removeMarkModalShow = ref(false)

const list = ref( [
  { name: 'John', id: 1 },
  { name: 'Joao', id: 2 },
  { name: 'Jean', id: 3 },
  { name: 'Gerard', id: 4 },
])
const log =(event)=>{
  console.log(event)
}

const editDataForm = reactive({
  id:"",
  chapterId:"",
  content: "",
  prompt: "",
  promptEn: "",
  orderNum: -1,
  characterName: "",
  startTime: null,
  lastStartTime: 0,
  endTime: 0,
  examplePic: ""
})

const addNum = ref(0)
const addModalShow = ref(false)
const addOrUpdateLoading = ref(false)
const randomScreentshotLoading = ref(false)

const props = defineProps({
  story: {
    type: Object,
    required: true
  }
})

// 列表字段
const createColumns = [
  {
    type: 'selection',
    multiple: false,
  },
  {
    title: '#',
    key: 'orderNum',
    width: 60
  },
  {
    title: '操作',
    width: 100,
    render (row) {
      const buttons = [h(
          NButton,
          {
            size: 'small',
            block: true,
            type: 'warning',
            onClick: () => deleteBoard(row)
          },
          { default: () => '删除',type:"error" }
      )]
      if(row.endTime - row.startTime > 2){
        buttons.push(h(
            NButton,
            {
              size: 'small',
              block: true,
              type: 'info',
              style: 'margin-top:5px;',
              onClick: () => addBoard(row)
            },
            { default: () => '插入' }
        ))
      }
      return  buttons
    }
  },

  {
    title: '开始时间',
    key: 'startTime',
    width: 100,
    onclick: (row: any) => {
      console.log(row)
    }
  },
  {
    title: '结束时间',
    key: 'endTime',
    width: 100,
  },
  {
    title: '文本内容',
    key: 'content',
    render(row, index) {
      return h(NInput, {
        value: row.content,
        type: 'textarea',
        style: 'height: 100px',
        onBlur() {
          if (videoTextList.value[index]?.isChange) {
            updateBoard(videoTextList.value[index])
          }
        },
        onUpdateValue(v) {
          if (v != videoTextList.value[index].content) {
            videoTextList.value[index].content = v
            videoTextList.value[index].isChange = true
          }
        }
      })
    }
  },
  {
    title: '本镜参考图',
    render(row) {
      if (row.examplePic) {
        return h(NImage, {
          lazy: true,
          height: '100',
          src: fileFunction.getViewFilePathByUserFileId(row.examplePic)
        })
      }
    }
  }
]


onMounted(() => {
  getVideoText()
})

const getVideoText = async () => {
  tableLoading.value = true
  storyController.getVideoText(props.story.id).then(res => {
    if (res.code === 200) {
      videoTextList.value = res.data
      videoTextList.value.forEach((item: any, index) => {
        item.key = index
      })
      getScreenshot()
    } else {
      message.error(res.msg)
    }
  }).finally(() => {
    tableLoading.value = false
  })
}

const batchScreenshot = async () => {
  if (videoTextList.value.length > 0) {
    const param = {
      storyId: props.story.id,
      screenshotType: extractOption.value,
      userFileId: props.story.userFileId,
      storyName: props.story.name
    }
    if(extractOption.value==='1'){
      totalNum.value = videoTextList.value.length * 3
    } else {
      totalNum.value = Math.floor(videoTextList.value[videoTextList.value.length-1].endTime)
    }
    await videoController.videoScreenshotAndCheckLog(param, 10 * 600 * 1000,progressModal , totalNum , finishNum).then(res => {
      totalNum.value = res.taskLog.totalNum
      finishNum.value = res.taskLog.finishNum
    })
    await getVideoText()

  }
}

const randomScreentshot = () => {
  const row = videoTextList.value[checkedRowKeys.value[0]]
  const exceptNumber = []
  randomScreentshotLoading.value = true
  picMap.get(checkedRowKeys.value[0]).forEach((item: any) => {
    exceptNumber.push(parseFloat(item.fileName)/1000)
  })
  const param = {
    startTime: row.startTime,
    endTime: row.endTime,
    userFileId: props.story.userFileId,
    screenshotNumber: 5,
    exceptNumber: exceptNumber
  }
  videoController.videoRandomScreenshotAndCheckLog(param, 10 * 600 * 1000).then(res => {
    getVideoText()
  }).finally(() => {
    randomScreentshotLoading.value = false
  })
}

const initialization = async () => {
  let storyBoardList = []
  videoTextList.value.forEach((item: any, index) => {
    let storyBoard = {
      id: "",
      orderNum: index,
      chapterId: props.story.id,
      content: item.content,
      startTime: item.startTime,
      endTime: item.endTime,
      examplePic: ''
    }
    let timeZonePic = getTimeZonePic(item.startTime, item.endTime)
    if (timeZonePic.length == 1) {
      storyBoard.examplePic = timeZonePic[0].userFileId
      storyBoardList.push(storyBoard)
    } else if (timeZonePic.length > 1) {
      storyBoard.examplePic = timeZonePic[1].userFileId
      storyBoardList.push(storyBoard)
    }
  })
  const data = {
    storyBoardList: storyBoardList
  }
  storyBoardController.initializationVideoStoryBoard(data).then(res => {
    if (res.code === 200) {
      message.success(res.msg)
    } else {
      message.error(res.msg)
    }
  })
}


/**
 * 获取截图
 */
const getScreenshot = async () => {
  const param = {
    storyId: props.story.id,
    userFileId: props.story.userFileId
  }
  await videoController.getScreenshotList(param).then(res => {
    if (res.code === 200) {
      screenshotList.value = res.data
      // 排序
      screenshotList.value.sort((a: any, b: any) => {
        return parseFloat(a.fileName) - parseFloat(b.fileName)
      })
      groupPic()
    } else {
      message.error(res.msg)
    }
  })
}


const updateBoard = (row: any) => {
  storyBoardController.addOrUpdateBoard(row).then(res => {
    if (res.code !== 200) {
      message.error(res.msg)
    }
  })
}


// 分组pic
const groupPic = () => {
  videoTextList.value.forEach((item: any, index: number) => {
    item.index = index
    let timeZonePic = getTimeZonePic(item.startTime, item.endTime)
    let hasChecked = false
    timeZonePic.forEach(pic => {
      if (item.examplePic) {
        if (item.examplePic == pic.userFileId) {
          pic.checked = true
          hasChecked = true
        } else {
          pic.checked = false
        }
      }
    })
    picMap.set(index, timeZonePic)
  })

  if(checkedRowKeys.value != null && checkedRowKeys.value.length > 0){
    filterScreenshotList.value = picMap.get(checkedRowKeys.value[0])
  }else {
    filterScreenshotList.value = picMap.get(0)
  }
}


const onUpdateCheckedRowKeys = (keys: any, rows: any) => {
  checkedRowKeys.value = keys
  filterScreenshotList.value = picMap.get(rows[0].index)
}


const getTimeZonePic = (startTime: number, endTime: number) => {
  return screenshotList.value.filter((item: any) => {
    return item.fileName > startTime * 1000 && item.fileName <= endTime * 1000
  })
}

const examplePicSelect = (imageFile: any) => {
  nextTick(() => {
    const picList = picMap.get(checkedRowKeys.value[0])
    if (imageFile.checked) {
      picList.forEach(pic => {
        pic.checked = false
      })
      imageFile.checked = true
      videoTextList.value[checkedRowKeys.value[0]].examplePic = imageFile.userFileId
    }
    // 更新updateBoard
    updateBoard(videoTextList.value[checkedRowKeys.value[0]])
  })
}


const imageDeduplication = () =>{
  const param = {
    storyId: props.story.id,
    storyName: props.story.name,
    similarity: similarity.value/100,
    userFileId: props.story.userFileId
  }
  imageDeduplicationLoading.value = true
  videoController.imageDeduplication(param).then(res => {
    if(res.code === 200){
      message.success(res.msg)
      deduplicationModalShow.value = false
      getVideoText()
    } else {
      message.error(res.msg)
    }
  }).finally(() => {
    imageDeduplicationLoading.value = false
  })
}


const addBoard = (row:any) =>{
  Object.keys(editDataForm).forEach(key => {
    editDataForm[key] = ''
  })
  addNum.value = row.orderNum
  editDataForm.orderNum = row.orderNum+1
  editDataForm.chapterId = props.story.id
  editDataForm.lastStartTime = row.startTime
  editDataForm.endTime = row.endTime
  addModalShow.value = true
}


const addOrUpdateBoard =()=>{
  const lastBoard = videoTextList.value[addNum.value]
  lastBoard.endTime = editDataForm.startTime
  let timeZonePic = getTimeZonePic(editDataForm.startTime, editDataForm.endTime)
  if (timeZonePic.length == 1) {
    editDataForm.examplePic = timeZonePic[0].userFileId
  } else if (timeZonePic.length > 1) {
    editDataForm.examplePic = timeZonePic[1].userFileId
  }
  const param = [editDataForm,lastBoard]
  console.log(param)
  addOrUpdateLoading.value = true
  storyBoardController.addOrUpdateBoards(param).then(res => {
    addOrUpdateLoading.value = false
    if(res.code === 200){
      message.success(res.msg)
      addModalShow.value = false
      getVideoText()
    }else {
      message.error(res.msg)
    }
  }).finally(() => {
    addOrUpdateLoading.value = false
  })
}

/**
 * 删除分镜
 * @param row
 */
const deleteBoard = (row:any) =>{
  window.$dialog.warning({
    title: "温馨提醒",
    content: "是否继续删除第("+ row.orderNum +")号分镜信息？",
    positiveText: "确定",
    negativeText: "取消",
    onPositiveClick: () => {
      storyBoardController.deleteBoard(row.id,row.chapterId).then(res => {
        if(res.code === 200){
          message.success(res.msg)
          getVideoText()
        }else {
          message.error(res.msg)
        }
      })
    }
  })
}

const loadSuccessEvent = ()=>{
  removeMarkModalShow.value = false
  getVideoText()
}

const nextStep = (callback: any) => {
  storyController.checkVideoRepaintStoryBoard(props.story.id, "2").then(res => {
    if (res.code === 200) {
      callback(true)
    } else {
      message.error(res.data);
      callback(false)
    }
  })
}

defineExpose({
  nextStep
})

</script>
